/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package it.tukano.odt;

import it.tukano.io.FileExt;
import it.tukano.lang.StringExt;
import it.tukano.swingdeco.containers.JPanelExt;
import it.tukano.swingdeco.controls.JButtonExt;
import it.tukano.swingdeco.controls.JComboBoxExt;
import it.tukano.swingdeco.input.PopupInput;
import it.tukano.swingdeco.list.JListExt;
import it.tukano.swingdeco.text.JTextAreaExt;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

/**
 *
 * @author utente4
 */
public class ScriptEvaluator {
    public static class StoredScript {
        private String name;
        private String script;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getScript() {
            return script;
        }

        public void setScript(String script) {
            this.script = script;
        }

        @Override
        public String toString() {
            return name;
        }
    }
    
    private static List<StoredScript> availableScripts = new ArrayList<StoredScript>();
    private static final ScriptEngine engine = new ScriptEngineManager().getEngineByMimeType("text/javascript");
    
    public static void reloadScripts(File folder) {
        if(folder.exists()) {
            availableScripts.clear();
            File[] files = folder.listFiles();
            if(files != null) for(File f : files) {
                StringExt name = StringExt.wrap(f.getName());
                if(name.toString().endsWith(".txt")) {
                    String script = new FileExt(f).getContentAsString("utf-8");
                    String scriptName = name.removeSuffix(".txt").toString();
                    StoredScript s = new StoredScript();
                    s.setName(scriptName);
                    s.setScript(script);
                    availableScripts.add(s);
                }
            }
        }
    }
    
    private final JButtonExt run = new JButtonExt("=").scaleFont(0.75).onAction(this, "evalScript");
    private final OdtFieldEditor owner;
    
    public ScriptEvaluator(OdtFieldEditor owner) {
        run.setFocusable(false);
        run.setUndecorated();
        run.setPreferredSize(new Dimension(24,16));
        this.owner = owner;
    }
    
    public Component getRunButton() {
        return run;
    }
    
    public void evalScript() {
        final JListExt scripts = new JListExt();
        scripts.setValues(ScriptEvaluator.availableScripts);
        final JTextAreaExt area = new JTextAreaExt();
        area.setFont(new Font("Monospace", Font.PLAIN, 12));
        scripts.onSelectionSet(new Runnable() {

            public void run() {
                Object item = scripts.getSelectedValue();
                if(item != null) {
                    StoredScript script = (StoredScript) item;
                    area.setText(script.getScript());
                }
            }
        });
        final JPanelExt content = new JPanelExt(new BorderLayout());
        if(scripts.getModel().getSize() > 0) {
            content.add(scripts.getScroller(), BorderLayout.EAST);
        }
        content.add(area.getScroller());
        content.setPreferredSize(new Dimension(300, 100));
        PopupInput.showConfirmPopup("Formula", owner, content, new Point(0, owner.getHeight()),  new Runnable() {

            public void run() {
                evalAndSet(area);
            }
        }, null);
    }
    
    private void evalAndSet(JTextAreaExt area) {
        evalAndSet(area.getText());
    }

    private void evalAndSet(String text) {
        try {
            owner.setValue(StringExt.wrap(engine.eval(text)));
        } catch (ScriptException ex) {
            ex.printStackTrace(System.err);
        }
    }
}
